package com.sky.common.generate.core;

import java.io.File;
import java.util.List;

public class GenerateXML extends GenerateBase {

    private String resultMapName = null;
    private String sqlIdName = null;

    public GenerateXML(GenerateBase generateBase) {
        super(generateBase.packagePath, generateBase.tableName, generateBase.moduleName, generateBase.className,
                generateBase.fieldList, generateBase.fieldMethod);
        fieldInfo = fieldInfoByPrimary();
        resultMapName = className + "Map";
        sqlIdName = className + "Columns";
    }

    public void execute() {
        StringBuilder builder = new StringBuilder();
        builder.append(generateMapper(packagePath, moduleName, "mapper", className, fieldList));
        writeGenerateFile(builder.toString().getBytes(), getGenerateXMLPath(moduleName, className));
    }

    /**
     * 获取生成路径
     **/
    private String getGenerateXMLPath(String moduleName, String className) {
        StringBuilder builder = new StringBuilder();
        builder.append(System.getProperty("user.dir"));
        builder.append(File.separator).append("src").append(File.separator).append("main").append(File.separator).append("resources").append(File.separator).append("mappers").append(File.separator);
        builder.append(moduleName).append(File.separator);
        builder.append(className).append("Mapper.xml");
        return builder.toString();
    }

    private String generateMapper(String packagePath, String moduleName, String domain, String className,
                                  List<FieldInfo> list) {
        String builder = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                + "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n"
                + "<mapper namespace=\"" + packagePath + "." + moduleName + "." + domain + "." + className + "Mapper"
                + "\">\n\n" +
                // 自定义映射
                generateResultMap(className, fieldInfo) +
                // 查询字段
                generateSqlField(list) +
                // 方法
                generateSelect(className, fieldInfo) + generateSelectList(className, fieldInfo, list)
                + /*generateInsert(className, tableName, list)+*/  generateInsertBatch(className, tableName, list)
                + /*generateUpdate(tableName, list) +*/ generateUpdateBatch(tableName, list)
                +/* generateDelete(sqlIdName, fieldInfo) +*/ generateDeleteBatch(tableName, list)
                + "</mapper>";
        return builder;
    }

    private FieldInfo fieldInfoByPrimary() {
        for (FieldInfo fi : fieldList) {
            if (fi.isPrimary()) {
                return fi;
            }
        }
        return null;
    }

    private String generateResultMap(String className, FieldInfo fieldInfo) {
        StringBuilder builder = new StringBuilder();
        builder.append("	<resultMap id=\"").append(resultMapName).append("\" ").append("type=\"").append(className)
                .append("\">\n");
        if (fieldInfo != null) {
            builder.append("		<id column=\"").append(fieldInfo.getColumnName()).append("\" property=\"")
                    .append(fieldInfo.getJavaColumnName()).append("\"/>\n");
        }
        builder.append("	</resultMap>\n\n");
        return builder.toString();
    }

    private String generateSqlField(List<FieldInfo> list) {
        return "	<sql id=\"baseColumns\">\n" + getSqlFields(list, true) + "\n	</sql>\n\n";
    }

    private String getSqlFields(List<FieldInfo> list, boolean isAlias) {
        StringBuilder builder = new StringBuilder();
        FieldInfo fieldInfo = null;
        int size = list.size();
        for (int i = 0; i < list.size(); i++) {
            fieldInfo = list.get(i);
            builder.append("		 ");
            if (isAlias) {
                builder.append(fieldInfo.getAlias()).append(".");
            }
            builder.append(fieldInfo.getColumnName());
            if ((i + 1) < size) {
                builder.append(",\n");
            }
        }
        return builder.toString();
    }

    private String getAttributeFields(List<FieldInfo> list) {
        StringBuilder builder = new StringBuilder();
        FieldInfo fieldInfo = null;
        int size = list.size();
        for (int i = 0; i < list.size(); i++) {
            fieldInfo = list.get(i);
            builder.append("		 ");
            builder.append("#{").append(fieldInfo.getJavaColumnName()).append("}");
            if ((i + 1) < size) {
                builder.append(",\n");
            }
        }
        return builder.toString();
    }

    private String getBatchAttributeFields(List<FieldInfo> list) {
        StringBuilder builder = new StringBuilder();
        FieldInfo fieldInfo = null;
        int size = list.size();
        for (int i = 0; i < list.size(); i++) {
            fieldInfo = list.get(i);
            builder.append("		 ");
            builder.append("#{emp.").append(fieldInfo.getJavaColumnName()).append("}");
            if ((i + 1) < size) {
                builder.append(",\n");
            }
        }
        return builder.toString();
    }

    private String generateSelect(String className, FieldInfo fieldInfo) {
        StringBuilder builder = new StringBuilder();
        if (this.fieldInfo != null) {
            if (fieldInfo.getComment() != null) {
                builder.append("	<!-- 根据").append(fieldInfo.getComment()).append("查询 -->\n");
            }
            builder.append("	<select id=\"findBy").append(upper(fieldInfo.getJavaColumnName()))
                    .append("\" resultMap=\"").append(className).append("Map\">\n");
            builder.append("		SELECT \n");
            builder.append("		 <include refid=\"baseColumns\" />\n");
            builder.append("		FROM ").append(fieldInfo.getTableName()).append(" ").append(fieldInfo.getAlias());
            builder.append(" WHERE ").append(fieldInfo.getAlias()).append(".").append(fieldInfo.getColumnName())
                    .append(" = #{").append(fieldInfo.getJavaColumnName()).append("}\n");
            builder.append("	</select>\n\n");
        }
        return builder.toString();
    }

    private String generateDelete(String sqlIdName, FieldInfo fieldInfo) {
        StringBuilder builder = new StringBuilder();
        if (fieldInfo != null) {
            if (fieldInfo.getComment() != null) {
                builder.append("	<!-- 根据").append(fieldInfo.getComment()).append("物理删除 -->\n");
            }
            builder.append("	<delete id=\"delBy").append(upper(fieldInfo.getJavaColumnName())).append("\">\n");
            builder.append("		DELETE FROM ").append(fieldInfo.getTableName()).append(" WHERE ")
                    .append(fieldInfo.getColumnName()).append(" = #{").append(fieldInfo.getJavaColumnName())
                    .append("}\n");
            builder.append("	</delete>\n\n");
        }
        return builder.toString();
    }

    private String generateDeleteBatch(String tableName, List<FieldInfo> list) {
        StringBuilder builder = new StringBuilder();
        builder.append("	<!-- 批量删除记录 -->\n");
        builder.append("	<delete id=\"delByIds\"").append(" parameterType = \"java.util.List\"").append(">\n");
        builder.append("		DELETE FROM ").append(tableName).append(" WHERE \n")
                .append("	    id in \n")
                .append("		<foreach collection=\"list\"  item=\"item\" open=\"(\" separator=\",\" close=\")\"  >\n")
                .append("		    #{item}\n")
                .append("		 </foreach>\n");
        builder.append("	</delete>\n\n");
        return builder.toString();
    }

    private String generateInsert(String className, String tableName, List<FieldInfo> list) {
        String sql = "	<!-- 插入记录 -->\n";
        sql += "	<insert id=\"insert";
        if (fieldInfo != null && fieldInfo.getColumnName() != null) {
            sql += "\" useGeneratedKeys=\"true\" keyProperty=\"" + fieldInfo.getColumnName() + "\""
                    + " parameterType=\"" + className;
        }
        sql += "\">\n";
        // 判断语句
        sql += "		INSERT INTO " + tableName + " (\n";
        sql += getSqlFields(list, false) + "\n";
        sql += "		) VALUES (\n";
        sql += getAttributeFields(list) + "\n		)\n";
        sql += "	</insert>\n\n";
        return sql.toString();
    }

    private String generateInsertBatch(String className, String tableName, List<FieldInfo> list) {
        String sql = "	<!-- 批量插入记录 -->\n";
        sql += "	<insert id=\"insertBatch";
        if (fieldInfo != null && fieldInfo.getColumnName() != null) {
            sql += "\" useGeneratedKeys=\"true\" keyProperty=\"" + fieldInfo.getColumnName() + "\""
                    + " parameterType=\"" + className;
        }
        sql += "\">\n";
        // 判断语句
        sql += "		INSERT INTO " + tableName + " (\n";
        sql += getSqlFields(list, false) + "\n";
        sql += "		) VALUES \n";
        sql += "		<foreach  item=\"emp\" separator=\",\" collection=\"list\"> \n";
        sql += "		(\n";
        sql += getBatchAttributeFields(list) + "\n		)\n";
        sql += "	    </foreach>\n";
        sql += "	</insert>\n\n";
        return sql.toString();
    }

    private String generateUpdate(String tableName, List<FieldInfo> list) {
        String sql = "	<!-- 更新记录 -->\n";
        sql += "	<update id=\"update\">\n";
        // 判断语句
        if (fieldInfo != null) {
            sql += "		UPDATE " + tableName + "\n";
            sql += "		<set>\n";
            for (FieldInfo f : list) {
                if (!f.isPrimary()) {
                    String condition = "";
                    String columnName = f.getColumnName();
                    String javaColumnName = f.getJavaColumnName();
                    if ("String".equals(f.getJavaDataType())) {
                        condition = " and " + javaColumnName + "!=''";
                    }
                    sql += "			<if test=\"" + javaColumnName + "!=null" + condition + "\">" + columnName
                            + " = #{" + javaColumnName + "},</if>\n";
                }
            }
            sql += "		</set>\n";
            sql += "		WHERE " + fieldInfo.getColumnName() + " = #{" + fieldInfo.getJavaColumnName() + "}\n";
        }
        sql += "	</update>\n\n";
        return sql.toString();
    }

    private String generateUpdateBatch(String tableName, List<FieldInfo> list) {
        String sql = "	<!-- 批量更新记录 -->\n";
        sql += "	<update id=\"updateBatch\">\n";
        sql += "		<foreach  item=\"emp\" separator=\";\" collection=\"list\">\n";
        // 判断语句
        if (fieldInfo != null) {
            sql += "		UPDATE " + tableName + "\n";
            sql += "		<set>\n";
            FieldInfo f = null;
            int size = list.size();
            for (int i = 0; i < list.size(); i++) {
                f = list.get(i);
                if (!f.isPrimary()) {
                    String condition = "";
                    String columnName = f.getColumnName();
                    String javaColumnName = f.getJavaColumnName();
                    if ("String".equals(f.getJavaDataType())) {
                        condition = " and emp." + javaColumnName + "!=''";
                    }
                    sql += "			<if test=\"emp." + javaColumnName + "!=null" + condition + "\">" + columnName
                            + " = #{emp." + javaColumnName + "}";
                    if ((i + 1) < size) {
                        sql += ",";
                    }
                    sql += "</if>\n";
                }
            }
            sql += "		</set>\n";
            sql += "		WHERE " + fieldInfo.getColumnName() + " = #{emp." + fieldInfo.getJavaColumnName() + "}\n";
        }
        sql += "		</foreach>\n";
        sql += "	</update>\n\n";
        return sql.toString();
    }

    private String generateSelectList(String className, FieldInfo fieldInfo, List<FieldInfo> list) {
        StringBuilder builder = new StringBuilder();
        if (this.fieldInfo != null) {
            if (fieldInfo.getComment() != null) {
                builder.append("	<!-- 列表  -->\n");
            }
            builder.append("	<select id=\"findList\" resultMap=\"").append(className)
                    .append("Map\">\n");
            builder.append("		SELECT \n");
            builder.append("		<include refid=\"baseColumns\" />\n");
            builder.append("        FROM ").append(fieldInfo.getTableName()).append(" ").append(fieldInfo.getAlias());
            builder.append(" WHERE 1=1\n");
            for (FieldInfo f : list) {
                String condition = "";
                String columnName = f.getColumnName();
                String javaColumnName = f.getJavaColumnName();
                if ("String".equals(f.getJavaDataType())) {
                    condition = " and " + javaColumnName + "!=''";
                }
                builder.append("        <if test=\"").append(javaColumnName).append("!=null").append(condition)
                        .append("\">AND ").append(fieldInfo.getAlias()).append(".").append(columnName).append(" = #{")
                        .append(javaColumnName).append("}</if>\n");

            }
            for (FieldInfo f : list) {
                if (f.isPrimary()) {
                    builder.append("        <if test=\"ids !=null and !ids.isEmpty\">\n             AND ")
                            .append(fieldInfo.getAlias()).append(".").append(f.getColumnName())
                            .append(" IN <foreach collection=\"ids\" item=\"id\" open=\"(\" separator=\",\" close=\")\">#{id}</foreach>\n        </if>\n");
                }
            }
            builder.append("	</select>\n\n");
        }
        return builder.toString();
    }
}
